/**
 * 模拟接口
 * @author luguoxiang
 * @Date: 2023/8/21 16:55
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
import message from "@/soar/utils/message";
import type {Api, Id} from "@/soar/types/Types";
import type {SoarQuery} from "@/soar/types/SoarQuery";

interface Data {
    /**
     * 数量
     */
    count?: number | [number, number];

    /**
     * 生成
     * @param i
     */
    gen(i: number): any;
}

interface Options {
    /**
     * 数据
     */
    data: any[] | ((i: number) => any) | Data;
    /**
     * id字段
     */
    idField?: string;
    /**
     * 超时时间
     */
    timeout?: number | [number, number];
    /**
     * 筛选数据
     */
    filter?(params: any, x: any, i?: number): any;
    /**
     * 名称
     */
    name?: string;
}

export default function createMock(optins: Options | ((i: number) => any)) {
    const {
        data,
        idField = 'id',
        timeout = [100, 1000],
        filter = (params: any, x: any) => x,
        name = '',
    } = typeof optins === "function" ? { data: optins } : optins;
    let list: any[];
    if (Array.isArray(data)) {
        list = data;
    } else {
        list = [];
        const cfg = typeof data === 'function' ? { gen: data } : data;
        const { count = 37, gen } = cfg as Data;
        for (let i = 0; i < count; i++) {
            list.push(gen(i));
        }
    }
    const getTime = Array.isArray(timeout) ? () => Math.random() * (timeout[1] - timeout[0]) + timeout[0] : () => timeout;
    return {
        query(params: SoarQuery) {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    const size = params.size || 10;
                    const end = (params.current || 1) * size;
                    const  result = list.filter((x, i) => filter(params, x, i));
                    const res = {
                        list: result.slice(end - size, end),
                        total: result.length,
                    }
                    console.log(name + ':mock:query', { params, res })
                    resolve({ data: JSON.parse(JSON.stringify(res)) });
                }, getTime())
            })
        },
        detail(id: string|number) {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    const res = list.find((x: any) => x[idField] == id);
                    console.log(name + ':mock:detail', { params: id, res })
                    resolve({ data: JSON.parse(JSON.stringify(res)) })
                }, getTime())
            })
        },
        create(data: any) {
            data = JSON.parse(JSON.stringify(data));
            console.log(name + ':mock:create', { data })
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    list.push(data);
                    resolve(null);
                }, getTime())
            })
        },
        update(data: any) {
            data = JSON.parse(JSON.stringify(data));
            console.log(name + ':mock:update', { data })
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    const id = data[idField];
                    const index = list.findIndex((x: any) => x[idField] === id);
                    if (index === -1) {
                        message.error('数据不存在');
                        return reject('数据不存在');
                    }
                    list[index] = {
                        ...list[index],
                        ...data,
                    };
                    resolve(null);
                }, getTime())
            })
        },
        remove(ids: Id | Id[]) {
            ids = JSON.parse(JSON.stringify(ids));
            console.log(name + ':mock:remove', { data: ids })
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    if (!Array.isArray(ids)) {
                        ids = [ids];
                    }
                    for (const id of ids) {
                        const index = list.findIndex((x: any) => x[idField] === id);
                        if (index !== -1) {
                            list.splice(index, 1);
                        }
                    }
                    resolve(null);
                }, getTime())
            })
        },
    } as Api
}
